package com.yc.star.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.yc.star.entity.Friend;
import com.yc.star.entity.User;
import com.yc.star.mapper.FriendMapper;
import com.yc.star.mapper.UserMapper;
import com.yc.star.service.IUService;
import org.apache.commons.math3.util.Pair;
import com.yc.star.utils.AlgorithmUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户 服务实现类
 * </p>
 *
 * @author ljl
 * @since 2024-06-13
 */
@Service
public class UServiceImpl extends ServiceImpl<UserMapper, User> implements IUService {

    @Resource
    UserMapper userMapper;

    @Resource
    FriendMapper friendMapper;

    @Override
    public List<User> matchUsers(long num, User loginUser) {

        LambdaQueryWrapper<Friend> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Friend::getUserid,loginUser.getId());
        List<Friend> friends = friendMapper.selectList(lqw);

        // 由于查询结果只包含 id 字段，你可以从 Friend 实体中获取 id
        List<Long> friendIds = friends.stream()
                .map(Friend::getFriendid)
                .collect(Collectors.toList());

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id", "tags");
        queryWrapper.isNotNull("tags");
        if (friendIds.size() > 0) {
            queryWrapper.notIn("id",friendIds);
        }
        List<User> userList = this.list(queryWrapper);//查询标签不为空的所有用户
        String tags = loginUser.getTags();
        System.out.println(tags);
        Gson gson = new Gson();
        //用户的标签
        List<String> tagList = gson.fromJson(tags, new TypeToken<List<String>>() {
        }.getType());
        // 用户列表的下标 => 相似度
        List<Pair<User, Long>> list = new ArrayList<>();
        // 依次计算所有用户和当前用户的相似度
        for (int i = 0; i < userList.size(); i++) {
            User user = userList.get(i);
            String userTags = user.getTags();
            // 无标签或者为当前用户自己
            if (user.getId().equals(loginUser.getId())) {
//                System.out.println("自己");
                continue;
            }
            List<String> userTagList = gson.fromJson(userTags, new TypeToken<List<String>>() {
            }.getType());
            // 计算分数
            long distance = AlgorithmUtils.minDistance(tagList, userTagList);
            list.add(new Pair<>(user, distance));
        }
        // 按编辑距离由小到大排序
        List<Pair<User, Long>> topUserPairList = list.stream()
                .sorted((a, b) -> (int) (a.getValue() - b.getValue()))
                .limit(num)
                .collect(Collectors.toList());
        // 原本顺序的 userId 列表
        List<Long> userIdList = topUserPairList.stream().map(pair -> pair.getKey().getId()).collect(Collectors.toList());
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.in("id", userIdList);
        // 1, 3, 2
        // User1、User2、User3
        // 1 => User1, 2 => User2, 3 => User3
        Map<Long, List<User>> userIdUserListMap = this.list(userQueryWrapper)
                .stream()
                .collect(Collectors.groupingBy(User::getId));
        List<User> finalUserList = new ArrayList<>();
        for (Long userId : userIdList) {
            finalUserList.add(userIdUserListMap.get(userId).get(0));
        }
        return finalUserList;
    }


}
